local skel = fk.CreateSkill{
  name = "lb__jishen",
}

Fk:loadTranslationTable{
  ["lb__jishen"] = "计神",
  --[":lb__jishen"] = "准备阶段，你可以卜算3，你可以将任意张手牌与观看牌交换。",
  --9.21
  [":lb__jishen"] = "准备阶段，你可以摸三张牌，然后将三张牌以任意顺序置于牌堆顶或牌堆底。",

  --["#lb__jishen"] = "计神：请卜算3，你可以将任意张手牌与观看牌交换",
  ["#lb__jishen"] = "计神：你可以摸三张牌，然后将三张牌以任意顺序置于牌堆顶或牌堆底",
  ["#lb__jishen_choose"] = "计神：请选择三张牌以任意顺序置于牌堆顶或牌堆底",

  ["$lb__jishen1"] = "互通有无，实为妙计。",
  ["$lb__jishen2"] = "以额间之眼观之…",
}

--[[
--- 询问玩家在自定义大小的框中排列卡牌（观星、交换、拖拽选牌）
---@param room Room
---@param player ServerPlayer @ 要询问的玩家
---@param params AskToArrangeCardsParams @ 各种变量
---@return table[] @ 排列后的牌堆结果
local askToArrangeCards = function (room, player, params)
  params.prompt = params.prompt or ""
  local areaNames = {}
  if type(params.card_map[1]) == "number" then
    params.card_map = {params.card_map}
  else
    for i = #params.card_map, 1, -1 do
      if type(params.card_map[i]) == "string" then
        table.insert(areaNames, 1, params.card_map[i])
        table.remove(params.card_map, i)
      end
    end
  end
  if #areaNames == 0 then
    areaNames = {params.skill_name, "toObtain"}
  end
  local cardMap = params.card_map
  params.box_size = params.box_size or 7
  params.max_limit = params.max_limit or {#cardMap[1], #cardMap > 1 and #cardMap[2] or #cardMap[1]}
  params.min_limit = params.min_limit or {0, 0}
  for _ = #cardMap + 1, #params.min_limit, 1 do
    table.insert(cardMap, {})
  end
  params.pattern = params.pattern or "."
  params.poxi_type = params.poxi_type or ""
  local data = {
    cardMap,
    params.prompt,
    params.box_size,
    params.max_limit,
    params.min_limit,
    params.free_arrange or false,
    areaNames,
    params.pattern or ".",
    params.poxi_type or "",
    ((params.pattern ~= "." or params.poxi_type ~= "") and (params.default_choice == nil)),
  }
  --[[
  local result = room:askToCustomDialog(player, { --用回老东西了
    skill_name = skel.name,
    qml_path = "packages/lb_kill/qml/ArrangeCardsBox.qml",
    extra_data = data,
  })
  --]
  local result = room:askToCustomDialog(player, {
    skill_name = skel.name,
    qml_path = "packages/lb_kill/qml/JiShenBox.qml",
    extra_data = data,
  })
  if result == "" then
    if params.default_choice then return params.default_choice end
    for j = 1, #params.min_limit, 1 do
      if #cardMap[j] < params.min_limit[j] then
        local cards = {table.connect(table.unpack(cardMap))}
        if #params.min_limit > 1 then
          for i = 2, #params.min_limit, 1 do
            table.insert(cards, {})
            if #cards[i] < params.min_limit[i] then
              for _ = 1, params.min_limit[i] - #cards[i], 1 do
                table.insert(cards[i], table.remove(cards[1], #cards[1] + #cards[i] - params.min_limit[i] + 1))
              end
            end
          end
          if #cards[1] > params.max_limit[1] then
            for i = 2, #params.max_limit, 1 do
              while #cards[i] < params.max_limit[i] do
                table.insert(cards[i], table.remove(cards[1], params.max_limit[1] + 1))
                if #cards[1] == params.max_limit[1] then return cards end
              end
            end
          end
        end
        return cards
      end
    end
    return cardMap
  end
  return result
end


skel:addEffect(fk.EventPhaseStart, {
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(skel.name) and target == player and data.phase == Player.Start
  end,
  on_cost = function (self, event, target, player, data)
    return player.room:askToSkillInvoke(player, {skill_name = skel.name, prompt = "#lb__jishen"})
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local ids = player:getCardIds("he")
    if #ids == 0 then return end
    local list = {
      ["top"] = room:getNCards(3),
      ["bottom"] = {},
      ["hand"] = player:getCardIds("h"),
      --["equip"] = player:getCardIds("e"),
      --["judge"] = player:getCardIds("j"),
    }
    room:moveCardTo(list["top"], Card.Processing, nil, fk.ReasonJustMove, skel.name, nil, false, player) -- 交换观看牌需要先放处理区，和正常卜算不同
    local get = askToArrangeCards(room, player, {
      skill_name = skel.name,
      card_map = {
        list["top"], list["bottom"], list["hand"],
        "Top", "Bottom", "$Hand"},
      prompt = "#lb__jishen",
      --box_size = 0,
      free_arrange = true,
      max_limit = {#list["top"], #list["top"], #list["hand"]},
      --min_limit = {0, min_num},
      --poxi_type = skel.name,
      --default_choice = {top, bottom, hand, equip, judge},
      default_choice = nil,
    })
    if get then
      local processing = {}
      for _, id in ipairs(list["hand"]) do
        for _, get_cards in ipairs({get[1], get[2]}) do
          if table.contains(get_cards, id) then
            table.insertIfNeed(processing, id)
          end
        end
      end
      if #processing > 0 then
        room:moveCardTo(processing, Card.Processing, nil, fk.ReasonJustMove, skel.name, nil, false, player)
      end
      local ids = table.filter(get[3], function (id)
        return table.contains(list["top"], id)
      end)
      if #ids > 0 then
        room:moveCards({
          ids = ids,
          to = player,
          toArea = Card.PlayerHand,
          moveReason = fk.ReasonExchange, --((i == 1) and fk.ReasonExchange or fk.ReasonPut),
          proposer = player,
          skillName = skel.name,
          moveVisible = false,
        })
      end
      if #get[1] > 0 then
        room:moveCards({
          ids = table.reverse(get[1]),
          toArea = Card.DrawPile,
          moveReason = fk.ReasonJustMove,
          proposer = player,
          skillName = skel.name,
          moveVisible = false,
          drawPilePosition = 1,
        })
      end
      if #get[2] > 0 then
        room:moveCards({
          ids = get[2],
          toArea = Card.DrawPile,
          moveReason = fk.ReasonJustMove,
          proposer = player,
          skillName = skel.name,
          moveVisible = false,
          drawPilePosition = -1,
        })
      end
      room:syncDrawPile()
      room:sendLog{
        type = "#GuanxingResult",
        from = player.id,
        arg = #get[1],
        arg2 = #get[2],
      }
    end
    room:cleanProcessingArea()
  end,
})
--]]
skel:addEffect(fk.EventPhaseStart, {
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(skel.name) and target == player and data.phase == Player.Start
  end,
  on_cost = function (self, event, target, player, data)
    return player.room:askToSkillInvoke(player, {skill_name = skel.name, prompt = "#lb__jishen"})
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    player:drawCards(3, skel.name)
    local ids = player:getCardIds("he")
    if #ids == 0 then return end
    if #ids > 3 then
      ids = room:askToCards(player, {
        min_num = 3,
        max_num = 3,
        skill_name = skel.name,
        cancelable = false,
        include_equip = true,
        prompt = "#lb__jishen_choose",
      })
    end
    local get = room:askToGuanxing(player, {
      cards = ids,
      skill_name = skel.name,
      skip = true,
    })
    if get == nil then return end
    if #get.top > 0 then
      room:moveCards({
        ids = table.reverse(get.top),
        from = player,
        toArea = Card.DrawPile,
        moveReason = fk.ReasonPut,
        proposer = player,
        skillName = skel.name,
        moveVisible = false,
        drawPilePosition = 1,
      })
    end
    if #get.bottom > 0 then
      room:moveCards({
        ids = get.bottom,
        from = player,
        toArea = Card.DrawPile,
        moveReason = fk.ReasonPut,
        proposer = player,
        skillName = skel.name,
        moveVisible = false,
        drawPilePosition = -1,
      })
    end
    room:syncDrawPile()
    room:sendLog{
      type = "#GuanxingResult",
      from = player.id,
      arg = #get.top,
      arg2 = #get.bottom,
    }
  end,
})

return skel